package com.qf.day09;

import com.qf.day08.homework.fight.Hero;

/**
 * 演示Object类的方法
 */
public class ObjectDemo {

    /**
     * 线程的概念： java中所有的方法都是有某个线程调用的
     * main，入口方法，是由一个特定的线程（名字也叫main线程）进行调用的
     * java是一个多线程程序，启动之后，除了main线程之外也由其他线程
     * 程序员也可以创建新的线程，并且让新的线程调用 指定的方法
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {

        Object o = new Object();
        // 什么是锁对象
        // 任何java对象都可以当初锁对象
        // synchronized 括号里面的对象，就是锁对象
        synchronized (o){
            System.out.println(Thread.currentThread().getName()+"进入了 同步 代码块");

            // 开启一个新的线程
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (o){ // 让worker线程申请锁
                        System.out.println(Thread.currentThread().getName()+"开始运行了");
                        try {
                            Thread.sleep(2000); // 让线程休眠两秒钟
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                        System.out.println(Thread.currentThread().getName()+"睡醒了，唤起main线程");
//                        o.notify(); // 唤醒在这个锁对象上等待的线程
                        o.notifyAll();
                    }
                }
            });  // 创建一个线程对象
            thread.setName("worker");
            thread.start(); // 启动线程

            // 让当前 线程 进入waiting状态，同时释放掉当前线程持有的 锁对象 使得其他线程可以获取 锁对象 ，让其他线程运行
            o.wait();
            System.out.println(Thread.currentThread().getName()+"从wait状态中醒来了");
        }




//        Object o = new Object();
//        System.out.println(o.hashCode());
//        System.out.println(o);


//        String s1 = "hello";
//        int h = s1.hashCode();
//        System.out.println(h);
//
//        String s2 = new String("hello");
//        System.out.println(s2.hashCode());


//        Hero hero1 = new Hero("永恩",100,30);

        // hashCode的作用，可以把任意一个java对象转换为一个int
        // 如果直接继承了父类Objec中的hashcode方法，这个hashcod可以代表对象的标识（主要受对象的内存地址影响）
//        int hashCode1 = hero1.hashCode();
//        System.out.println(hashCode1);
//
//        Hero hero2 = new Hero("永恩",100,30);
//        int hashedCod2 = hero2.hashCode();
//        System.out.println(hashedCod2);


//        Class c1 = hero1.getClass(); // 获得这个对象所属的类的对象
//        // hero1的所属的类的名字是什么
//        System.out.println(c1.getName());

//        Object o = new Object();
//        Class c2 = o.getClass();
//        System.out.println(c2.getName());

        // 重写Object类中的equals方法
//        Hero hero1 = new Hero("永恩",100,30);
//        Hero hero2 = new Hero("永恩",100,30);

        // 如果直接使用Object类中继承的equals方法，可能不符合我们的需求
        // this == obj ， 在比较的对象的地址，如果两个对象的属性完全相同，那么地址不同，也会返回false
        // 如果需要两个对象属性相同时，返回true，需要重写 equals方法
//        boolean equals = hero1.equals(hero2);
//        System.out.println(equals);

//        System.out.println(hero1.equals(null));


//        String s1 = "hello";
//        String s2 = "hello";
//        boolean equals = s1.equals(s2);
//        System.out.println(s1==s2);
//        System.out.println(equals);
//
//        String s3 = new String("hello");
//        System.out.println(s1==s3);
//        System.out.println(s1.equals(s3));




        // 创建对象的过程 申请空间，初始值，构造，返回地址
//        Object o1 = new Object();
//        Object o2 = new Object();
//
//        // equals
//        boolean equals = o1.equals(o2);
//        System.out.println(equals);
//
//        System.out.println(o1.equals(o1));
    }
}
